package com.ease.util {

import flash.system.ApplicationDomain;

import mx.core.IFlexModuleFactory;

/**
 * @private
 *
 */
public class ObjectFactory
{
   private var _classDefn:Class;
   private var _typeName:String;
   private var _moduleFactory:IFlexModuleFactory;

   public var constructionListener:Function;

   public static function
   newFactoryByClass( classDefn:Class,
                      constructionListener:Function = null ):ObjectFactory {
      var factory:ObjectFactory = new ObjectFactory();
      factory._classDefn = classDefn;
      factory.constructionListener = constructionListener;
      return factory;
   }

   public static function
   newFactoryByTypeName( typeName:String, moduleFactory:IFlexModuleFactory,
                         constructionListener:Function = null ):ObjectFactory {
      var factory:ObjectFactory = new ObjectFactory();
      factory._typeName = typeName;
      factory._moduleFactory = moduleFactory;
      factory.constructionListener = constructionListener;
      return factory;
   }

   /**
    *
    * @param constructorArg
    *  Argument for the constructor; null implies no-arg construction
    *
    * @return
    *  A new instance of the specified type if successful; otherwise throws an exception
    *  or returns null
    */
   public function newInstance( constructorArg:* = null ):* {
      var instance:*;
      if (_classDefn) {
         if (constructorArg) {
            instance = new _classDefn( constructorArg );
         } else {
            instance = new _classDefn();
         }
      }
      if (_typeName && _moduleFactory) {
         if (constructorArg) {
            // We can't use _moduleFactory.create in this case because it doesn't
            // use the constructorArg param (at least in Flex 4).
            // So we need to get the type and call instantiate on it.
            var appDomain:ApplicationDomain = _moduleFactory.info().currentDomain;
            var classDefn:Class = appDomain.getDefinition(_typeName) as Class;
            instance = new classDefn( constructorArg );
         } else {
            instance = _moduleFactory.create( _typeName );
         }
      }
      if (instance && constructionListener != null) {
         constructionListener( instance );
      }
      return instance;
   }
}

}